﻿using System;
using System.Reflection;
#if WPF
using System.Windows.Media;
using System.Windows.Controls;
using System.IO;
using System.Windows.Media.Imaging;
#else
using System.Drawing;
using System.IO;
#endif

namespace Inaction.Util
{
    public static class TypeConvert
    {
        #region IsNumber

        public static bool IsNumber(this ValueType value)
        {
            return value is Byte ||
               value is Int16 ||
               value is Int32 ||
               value is Int64 ||
               value is SByte ||
               value is UInt16 ||
               value is UInt32 ||
               value is UInt64 ||
               value is Decimal ||
               value is Double ||
               value is Single;
        }
        public static bool IsDateTime(this Type type)
        {
            return type == typeof(DateTime) || type == typeof(Nullable<DateTime>);
        }

        #endregion

        #region GetUnderlyingType
        public static Type GetUnderlyingType(this Type type)
        {
            if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                return Nullable.GetUnderlyingType(type);
            }
            else
            {
                return type;
            }
        }
        #endregion

        #region TypeValueConvert
        public static object ConvertToDbValue(object value)
        {
            if (value == null) return value;
            if (value.GetType().IsEnum)
            {
                return (int)value;
            }
            if (value is Color)
            {
                return ((Color)value).ToArgb();
            }
            if (value is string)
            {
                if ((value as string).Equals("TRUE", StringComparison.OrdinalIgnoreCase)) return true;
                if ((value as string).Equals("FALSE", StringComparison.OrdinalIgnoreCase)) return false;
            }
            if (value is Image)
            {
#if WPF
                var image = value as BitmapImage;
                var buf = new byte[image.StreamSource.Length];
                image.StreamSource.Read(buf, 0, (int)image.StreamSource.Length);
                return buf;
#else
                using (var ms = new MemoryStream())
                {
                    var image = value as Image;
                    image.Save(ms, image.RawFormat);
                    return ms.ToArray();
                }
#endif
            }
            return value;
        }
        public static object ConvertToSystemValue(Type type, object dbValue)
        {
            if (type.Equals(typeof(bool)))
            {
                return dbValue.Equals(true) || dbValue.Equals(1);
            }
            if (type.IsEnum)
            {
                return Enum.Parse(type, dbValue.ToString());
            }
            if (type.Equals(typeof(Color)))
            {
#if WPF
                var color = new Color();
                return color.FromArgb((int)dbValue);
#else
                return Color.FromArgb((int)dbValue);
#endif
            }
            if (type == typeof(Image) && dbValue.GetType() == typeof(byte[]))
            {
                using (var ms = new MemoryStream(dbValue as byte[]))
                {
#if WPF
                    var image = new BitmapImage();
                    image.BeginInit();
                    image.StreamSource = ms;
                    image.EndInit();
                    return image;
#else
                    return Image.FromStream(ms);
#endif
                }
            }
            return Convert.ChangeType(dbValue, type);
        }
        #endregion
    }
}